package cn.green.core.components.table.t;

import cn.green.core.components.table.TableTypeCom;
import cn.green.core.model.QCondition;
import cn.green.core.model.QTable;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wang.yishu
 * @version 1.0
 * @className QTreeTable
 * @description Q组件本身提供的树类型
 * @date 2025/2/28 10:01
 */
public abstract class QTreeTable implements TableTypeCom {

    @Override
    public boolean canBuildConditionSql() {
        return false;
    }
    @Override
    public JSONArray arrangeData(JSONArray data, QTable table, JSONObject param) {
        JSONObject root = new JSONObject();
        root.put(this.getPrimaryKeyField().getFieldName(), this.getParentKeyField().getDefaultValue());
        this.buildTree(table, data, root, param, false);
        return root.getJSONArray("children");
    }

    @Override
    public JSONObject arrangeDetail(JSONObject detail, QTable table) {
        return detail;
    }


    public boolean buildTree(QTable table, JSONArray data, JSONObject parent, JSONObject param, boolean parentHit) {
        String parentPrimaryKey = this.getPrimaryKeyField().getFieldName();
        String parentKey = this.getParentKeyField().getFieldName();
        //得到父级id
        Object parentId = parent.get(parentPrimaryKey);
        //父级是否命中
        boolean hit = QCondition.Compare.compare(table, parent, param);
        boolean childHit = false;
        boolean currentHit = false;
        if (data != null && !data.isEmpty()) {
            List<Object> children = data.stream().filter(item -> parentId.equals(((JSONObject) item).get(parentKey))).collect(Collectors.toList());
            if (!children.isEmpty()) {
                List<JSONObject> childrenTarget = null;
                for (Object child : children) {
                    JSONObject childJsonObject = (JSONObject) child;
                    childHit = this.buildTree(table, data, childJsonObject, param, hit);
                    if (!currentHit && childHit) {
                        currentHit = true;
                    }
                    if (childHit || hit || parentHit) {
                        if (childrenTarget == null) {
                            childrenTarget = new ArrayList<>();
                        }
                        childrenTarget.add(childJsonObject);
                    }
                }
                parent.put("children", childrenTarget);
            }
        }
        return hit || childHit || currentHit || parentHit;
    }
}
